﻿using System;
// 4.3 Lambda表达式
// Lambda表达式时写在委托实例上的匿名方法。编译器立即将lambda表达式转换成下面的两种情形其中的一种：
//    委托实例
//    Expression<Tdelegate>类型的表达式树，该表达式树lambda表达式内的代码显示为可遍历的对象模式。这使得对lambda表达式的解释可以延迟到运行时。
namespace _098_Lambda表达式
{
    //下面的委托类型：
    delegate int Transformer(int i);
    
    class Program
    {
        static void Main(string[] args)
        {
            //可以指定和调用下面的x=>x*x lambda表达式
            Transformer sqr = x => x * x;
            Console.WriteLine(sqr(3)); // 9

            //提示：编译器在内部将这种lambda表达式编译成一个私有方法，并把表达式代码移到该方法中。

            // Lambda表达式有以下形式：
            //(参数) => 表达式或语句块
            // 为了方便，在只有一个可推测类型的参数时，可以省略小括号。
            //本例中，只有一个参数x，表达式x*x
            //x => x * x;
            // Lambda表达式使每个参数和委托的参数一致，表达式的类型（可以为void）和委托的返回值类型一致。
            //在本例中，x和参数i一致，表达式x*x的返回值类型int一致，因此它和Transformer委托相兼容：
            //delegate int Transformer(int i);
            // Lambda表达式代码除了可以是表达式还可以是语句块。我们可以把上例改写成：
            //x => { return x * x; }
            // Lambda表达式通常和Func或Action委托一起使用，因此可以将前面的表达式携程下面的形式：
            Func<int, int> sqr1 = x => x * x;
            //下面是一个带两个参数的表达式实例：
            Func<string, string, int> totalLength = (s1, s2) => s1.Length + s2.Length;
            int total = totalLength("hello", "world"); // total的值是10
            //Lambda表达式是C#3.0中引入的概念。


            //4.3.1 明确指定Lambda参数类型
            // 编译器通常可以根据上下文推断出lambda参数的类型。但当不能推断时，必须明确指定每个参数的类型。
            //例如下面的表达式：
            Func<int, int> sqr2 = x => x * x;
            //编译器可以推断x是int型。也可以显式指定x的类型：
            Func<int, int> sqr3 = (int x) => x * x;


            Console.ReadKey();
        }
    }
}
